<?php

namespace app\admin\controller\kuerp;

use addons\kuerp\model\Flows;
use addons\kuerp\model\Message;
use app\admin\model\Admin;
use app\admin\model\department\Admin as AdminDepartment;
use app\common\controller\Backend;
use think\Db;
use think\Exception;

/**
 * 公章申请管理
 *
 * @icon fa fa-circle-o
 */
class Commonseal extends Backend
{

    /**
     * Commonseal模型对象
     * @var \app\admin\model\kuerp\Commonseal
     */
    protected $model = null;
    protected $flows = [];
    protected $examine_index = 0;
    protected $adminids = [];
    protected $last_examine_indexs = [];//获取审批流程中当前用户可审核的级数 0开始
    protected $first_children_ids = [];//当前用户直属下级人员
    protected $is_last_step = false;//当前用户是否审核流程最后一级
    protected $noNeedRight = ['detail'];

    public function _initialize()
    {
        parent::_initialize();
        $this->assignconfig('edit_auth',$this->auth->check('kuerp/commonseal/edit'));
        $this->assignconfig('del_auth',$this->auth->check('kuerp/commonseal/del'));
        $this->assignconfig('approvedEdit',$this->auth->check('kuerp/commonseal/approvedEdit'));

        $this->model = new \app\admin\model\kuerp\Commonseal;
        $this->view->assign("commonSealList", $this->model->getCommonSealList());
        $this->view->assign("usedeatilList", $this->model->getUsedeatilList());

        $checkStatusList = $this->model->getCheckStatusList();
        $this->view->assign("checkStatusList", $checkStatusList);
        $this->assignconfig("checkStatusList", $checkStatusList);
        $action = $this->request->action();
        $adminids = $this->auth->adminids;
        //系统设置特定审核人员
        $config_examine_admins = config('site.examine_admins');
        if (!empty($config_examine_admins[$this->auth->id])) {
            //获取对应销售id
            $adminids = array_merge($adminids,explode(',',$config_examine_admins[$this->auth->id]));
        }
        $this->adminids = $adminids;
        if (in_array($action, ['examinelist', 'detail', 'examine'])) {
            //获取审批流程
            $flows = Db::name('flows')->where('relation_type', 'common_seal')->where('status', 1)->find();
            if (empty($flows)){
                $this->error('请先设置并启用公章申请审批流程');
            }
            $flows['flow_items'] = json_decode($flows['flow_items'], true);
            //判断流程中是否有当前用户审核
            $examine_index = 0;
            foreach ($flows['flow_items'] as $key => $value) {
                if (in_array($this->auth->id, explode(',',$value['admin_id'])) ) {
                    $examine_index = $key + 1;
                    $this->last_examine_indexs[] = $key;
                    // break;
                }
            }
            //当前用户存在多级审核且存在第一级审核时 需要获取该用户的直属下级
            $search_index = array_search(0, $this->last_examine_indexs);
            if(count($this->last_examine_indexs) > 1 && $search_index !== false) {
                //获取直属下级
                $department_ids = AdminDepartment::getPrincipalIds($this->auth->id);
                if ($department_ids) {
                    $children_ids = AdminDepartment::getDepartmentAdminIds($department_ids, true);
                    $children_ids = array_unique(array_merge($children_ids, !empty($config_examine_admins[$this->auth->id]) ? explode(',', $config_examine_admins[$this->auth->id]) : []));
                    $this->first_children_ids = $children_ids?$children_ids:[];
                }
                $this->last_examine_indexs = array_values(array_diff($this->last_examine_indexs, [0]));
            }
            if ($examine_index == 0 && !$this->auth->isSuperAdmin() && $action != 'detail') {
                $this->error('您不在审批流程中');
            }
            $this->examine_index = $examine_index;
            $this->flows = $flows;
            if ($this->examine_index == count($flows['flow_items'])) {
                $this->is_last_step = true;
            }
        }
    }



    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */

    public function index()
    {
        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            $wheres = [];
            if (!$this->auth->isSuperAdmin()) {
                $wheres['admin_id'] = ['in', $this->adminids];
            }
            $wheres['id'] = ['exp', Db::raw(' > 0 and ((check_status = 0 and admin_id = '.$this->auth->id.') or check_status > 0)')];
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = $this->model
                ->where($wheres)
                ->where($where)
                ->order($sort, $order)
                ->paginate($limit);

//            foreach ($list as $row) {
//                $row->visible(['id','apply_code','total_score','add_score','goodssales_id','goodssales_code','admin_id','pay_status','createtime','check_status']);
//            }
            if ($list->items()) {
                $adminids = array_column($list->items(), 'check_last_uid');
                $adminlist = Db::name('admin')->where('id', 'in', $adminids)->column('nickname,avatar', 'id');
                foreach ($list as $key => $value) {
                    $list[$key]['last_checkadmin'] = $adminlist[$value['check_last_uid']] ?? [];
                }
            }

            $result = array("total" => $list->total(), "rows" => $list->items());

            return json($result);
        }
        //获取申请人列表 搜索
        $adminids = $this->adminids;
        $adminlist = Admin::where('id', 'in', $adminids)->column('nickname','id');
        $this->assignconfig('adminlist', $adminlist);
        $this->assignconfig("commonSealList", $this->model->getCommonSealList());
        $this->assignconfig("usedeatilList", $this->model->getUsedeatilList());
        //审核人
        $flows = Db::name('flows')->where('relation_type', 'common_seal')->where('status', 1)->find();
        $examine_adminids = [];
        if (!empty($flows)) {
            $flows['flow_items'] = json_decode($flows['flow_items'], true);
            foreach ($flows['flow_items'] as $key => $value) {
                $examine_adminids = array_merge($examine_adminids, explode(',',$value['admin_id']));
            }
        }
        $examine_admins = Admin::where('id', 'in', $examine_adminids)->column('nickname','id');
        $this->assignconfig('examine_admins', $examine_admins);
        return $this->view->fetch();
    }

    public function add()
    {
        if ($this->request->isPost()) {
            $params = $this->request->post('row/a');
            Db::startTrans();
            try {
                $result = $this->model->addCommonSeal($params);
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            $this->success('添加成功');
        }
        return $this->view->fetch();
    }

    public function edit($ids = null)
    {
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
        }
        if($row['check_status']==1){
            $this->error('不能编辑审核中的数据');
        }
        if($row['check_status']==2){
            $this->error('不能编辑已审核的数据');
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);
        $result = false;
        Db::startTrans();
        try {
            $result = $this->model->editCommonSeal($params, $row);
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }

    public function examinelist()
    {
        //当前是否为关联查询
        $this->relationSearch = false;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);

        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            $wheres = [
                'admin_id' => ['in', $this->adminids]
            ];
            $filter = json_decode($this->request->get("filter", ''), true);
            $op = json_decode($this->request->get("op", '','trim'), true);

            if (isset($filter['check_status'])) {
                // 自定义处理
                $check_status = $filter['check_status'];
                // 处理完可以去掉也可以覆盖重构
                unset($filter['check_status'],$op['check_status']);
            } else if ($this->request->get('check_status') !== null){
                $check_status = $this->request->get('check_status');
            }
            $check_status = isset($check_status) ? $check_status : 0;
            if ($check_status == 1) {
                $wheres['id'] = ['exp', Db::raw(' > 0 and FIND_IN_SET('.$this->auth->id.',check_history_uids)')];
                // $wheres['check_status'] = ['exp', Db::raw('=2 OR (check_status="1" AND (check_step_sort >= '.($this->examine_index ? : 1).' OR FIND_IN_SET('.$this->auth->id.',`check_uids`)))')];
            }else{
                $wheres['check_status'] = '1';
                if (!empty($this->first_children_ids)) {
                    if ($this->last_examine_indexs) {
                        $wheres['id'] = ['exp', Db::raw('> 0 and ( (check_step_sort = 0 and admin_id in ('.implode(',', $this->first_children_ids).'))  OR (check_step_sort '.(count($this->last_examine_indexs) == 1 ? '='.$this->last_examine_indexs[0] : ' in ('.implode(',', $this->last_examine_indexs).')').' and admin_id in ('.implode(',', $this->adminids).')))')];
                    } else {
                        $wheres['check_step_sort'] = 0;
                    }
                } else {
                    $wheres['check_step_sort'] = count($this->last_examine_indexs) == 1 ? $this->last_examine_indexs[0] : ['in', $this->last_examine_indexs];
                }
                // $wheres['check_step_sort'] = $this->examine_index - 1;//不可跨级
                $wheres['check_uids'] = ['exp', Db::raw('="" OR FIND_IN_SET('.$this->auth->id.',check_uids) = 0')];
            }
            $this->request->get(['filter'=>json_encode($filter,true)]);
            $this->request->get(['op'=>json_encode($op,true)]);
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = $this->model
                ->where($where)
                ->where($wheres)
                ->order($sort, $order)
                ->paginate($limit);
//            echo $this->model->getLastSql();
            // foreach ($list as $row) {
            //     $row->visible(['id','apply_code','total_score','add_score','goodssales_id','goodssales_code','admin_id','pay_status','createtime','check_status', 'check_last_uid']);
            // }
            if ($list->items()) {
                // $admins = array_column($list->items(), 'admin_id');
                $adminids = array_column($list->items(), 'check_last_uid');
                $adminlist = Db::name('admin')->where('id', 'in', $adminids)->column('nickname,avatar', 'id');
                foreach ($list as $key => $value) {
                    // $list[$key]['admin'] = $adminlist[$value['admin_id']] ?? [];
                    $list[$key]['last_checkadmin'] = $adminlist[$value['check_last_uid']] ?? [];
                    if ($check_status == 0) {
                        $list[$key]['check_status'] = $value['check_status'] == 1 ? 0 : $value['check_status'];
                    } else {
                        //获取最后一条审核日志
                        $last_status = Db::name('examine_log')->where(['relation_type' => 'common_seal', 'relation_id' => $value['id'], 'admin_id' => $this->auth->id])->order('id desc')->value('examine_status');
                        $list[$key]['check_status'] = $last_status == 0 ? 3 : 2;
                    }

                }
            }
            $result = ["total" => $list->total(), "rows" => $list->items()];

            return json($result);
        }
        //获取报销人列表 搜索
        $adminlist = Db::name("admin")->where("id", 'in', $this->adminids)->column("nickname","id");
        $this->assignconfig("adminlist", $adminlist);
        $this->assignconfig("commonSealList", $this->model->getCommonSealList());
        $this->assignconfig("usedeatilList", $this->model->getUsedeatilList());
        return $this->view->fetch();
    }

    public function detail($ids)
    {
        $row = $this->model->getInfo($ids);
        $row['admin'] = Admin::where('id', $row['admin_id'])->field('nickname,avatar')->find();
        $row['createtime_text'] = date('Y-m-d H:i:s', $row['createtime']);
        $this->view->assign('row', $row);
        $flows = Flows::getstepdetail(Flows::COMMON_SEAL, $ids);
        $this->assign('stepList',$flows['stepList']);
        $this->assign('ids',$ids);
        //判断是否可审核
        $can_examine = false;
        $enableExamine = $this->auth->check('kuerp/commonseal/examine');
        if ($enableExamine && $this->examine_index > 0 && $row['check_status'] == 1) {
            if (!empty($this->first_children_ids)) {
                if ($this->last_examine_indexs) {
                    if (($row['check_step_sort'] == 0 && in_array($row['admin_id'], $this->first_children_ids)) || (in_array($row['check_step_sort'], $this->last_examine_indexs) && in_array($row['admin_id'], $this->adminids))) {
                        $can_examine = true;
                    }
                } else {
                    if ($row['check_step_sort'] == 0) {
                        $can_examine = true;
                    }
                }
            } else {
                if (in_array($row['check_step_sort'], $this->last_examine_indexs)) {
                    $can_examine = true;
                }
            }
        }
        $this->view->assign('can_examine', $can_examine);
        //判断是否审核流程最后一级 最后一级可以加赠积分
        $this->view->assign('is_last_step', $this->is_last_step);
        $this->assignconfig('is_last_step', $this->is_last_step);
        $this->assignconfig('yuming', $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME']);

        //标记通知已读
        Message::setRead(Message::COMMON_SEAL, $ids, $this->auth->id);
        return $this->view->fetch();
    }

    public function examine($ids)
    {
        $status = $this->request->post("status");//1通过 0拒绝
        $remark = $this->request->post("remark", '');
        $row = $this->model->get($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        if (!$status) {
            if (empty($remark)) {
                $this->error('请填写审批不通过原因');
            }
        }
        $log = [
            'flows_id' => $this->flows['id'],
            'relation_type' => 'common_seal',
            'relation_id' => $row['id'],
            'cur_index' => $this->examine_index,
            'admin_id' => $this->auth->id,
            'examine_status' => $status,
            'remark' => $remark,
            'createtime' => time(),
        ];
        $update = [
            'check_status' => $status ? $row['check_status'] : 3,
            'check_remark' => $remark,
            'check_last_uid' => $this->auth->id,
            'check_step_sort' => $status ? $this->examine_index : 0,//审核拒绝回到最开始
            'check_uids' => '',//
        ];
        //判断这一级审批类型 stafftype=1 任意一人审批； stafftype=2 多人会签
        $flow_item = $this->flows['flow_items'][$this->examine_index - 1] ?? [];
        if ($status && !empty($flow_item['stafftype']) && $flow_item['stafftype'] == 2) {
            //查看其他人是否已审核
            if ($flow_item['admin_id'] != (string)$this->auth->id) {
                //这一级需要审核的人员
                $admin_ids = explode(',', $flow_item['admin_id']);
                //这一级已审核的人员
                $sale_adminids = $row['check_step_sort'] == $this->examine_index && $row['check_uids'] ? explode(',', $row['check_uids']) : [];
                $sale_adminids[] = $this->auth->id;
                $sale_adminids = array_intersect($admin_ids,$sale_adminids);
                if (count($sale_adminids) < count($admin_ids)) {
                    unset($update['check_step_sort']);
                    $update['check_uids'] = $row['check_uids'] ? $row['check_uids'] . ',' . $this->auth->id : $this->auth->id;
                }
            }
        }
        //如果申请人本身在审批人员中，判断退回到该申请人所在审批步骤
        if (!$status) {
            $examine_index = 0;
            foreach ($this->flows['flow_items'] as $key => $value) {
                if (in_array($row['admin_id'], explode(',',$value['admin_id'])) ) {
                    $examine_index = $key + 1;
                    // break;
                }
            }
            $update['check_step_sort'] = $examine_index;
        }
        $update['check_history_uids'] = $row['check_history_uids'] ? $row['check_history_uids'] . ',' . $this->auth->id : $this->auth->id;
        $update['check_history_uids'] = $status ? $update['check_history_uids'] : '';//拒绝清空已审批人
        //最后一级审批
        if ($status && !empty($update['check_step_sort']) && $this->examine_index == count($this->flows['flow_items'])){
            $update['check_status'] = 2;
            $update['check_time'] = time();
        }

        $result = false;
        Db::startTrans();
        try {
            $logid = Db::name('examine_log')->insertGetId($log);

            $result = $this->model->where(['id'=>['in',$ids]])->update($update);
            if ($message = Message::where(['relation_type' => 'examine', 'relation_id' => $row['id'], 'to_staff_id' => $this->auth->id])->find()) {
                Message::where(['id' => $message['id']])->update(['status' => 1, 'read_time' => time()]);
            }
            if ($status) {
                $flow = Flows::getFlowByTypes(Flows::COMMON_SEAL);
                //给下一审核人发送通知
                $check_staff_ids = $update['check_history_uids'];
                $result = Flows::sendStepRecord($flow, Flows::COMMON_SEAL, $row['id'], $check_staff_ids, $update['check_step_sort'] ?? $row['check_step_sort']);
                //完成审批发送
                if ($update['check_status'] == 2) {
                    Message::addMessage(Message::EXAMINE_ADOPT_TYPE, $logid, $row['admin_id'], $this->auth->id);
                }
            } else {
                Message::addMessage(Message::EXAMINE_REFUSE_TYPE, $logid, $row['admin_id'], $this->auth->id, '');
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($result !== false) {
            $this->success();
        } else {
            $this->error('审核失败');
        }
    }


}
